package com.easy.neo4j.aspect;

import com.easy.common.exception.ExceptionEnum;
import com.easy.neo4j.exception.CheckParamException;
import com.easy.neo4j.annotation.CheckParam;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Objects;

/**
 * @Author: CoolPro
 * @Description:
 * @Time: 2024-04-19 19:08
 **/
@Component
@Aspect
public class CheckParamAroundAspect {

    //对所有controller方法施加参数校验的判断
    @Before("execution(* com.easy.neo4j.controller.*.*(..))")
    public void checkParam(JoinPoint joinPoint) throws NoSuchFieldException, IllegalAccessException {
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            Class clazz = arg.getClass();
            //把arg的值赋给clazz
            if(!clazz.isPrimitive()){
                //判断是否是基础类型
                Field[] declaredFields = clazz.getDeclaredFields();
                for (Field field : declaredFields) {
                    CheckParam annotation = field.getAnnotation(CheckParam.class);
                    if (Objects.nonNull(annotation)) {
                        if(annotation.required()){
                            Field fd = clazz.getDeclaredField(field.getName());
                            fd.setAccessible(true);
                            Object value = fd.get(arg);
                            fd.setAccessible(false);
                            if(Objects.isNull(value)){
                                throw new CheckParamException(ExceptionEnum.PARAM_NOT_FOUND);
                            }
                        }
                        if(annotation.rangeValue().length>0){
                            Field fd = clazz.getDeclaredField(field.getName());
                            fd.setAccessible(true);
                            Object val = fd.get(arg);
                            if(val==null){
                                return;
                            }
                            fd.setAccessible(false);
                            if (Arrays.stream(annotation.rangeValue()).noneMatch(s -> s.equals(val))){
                                throw new CheckParamException(ExceptionEnum.PARAM_NOT_FOUND);
                            }
                        }
                    }
                }
            }
        }
    }
}


